#include <iostream>
#include "hs_rasterview.h"

template<typename DataType>
void printmat(const hs::raster::RasterView<DataType>& mat)
{
    for (int y = 0; y < mat.sizeY(); ++y) {
        for (int x = 0; x < mat.sizeX(); ++x) {
            std::cout << mat(x, y) << ", ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
}

template<typename DataType>
void printSymmetric(hs::raster::RasterView<DataType>& mat)
{
    int pad_size_x = 1;
    int pad_size_y = 1;
    mat.setPadding(pad_size_x, pad_size_y, hs::raster::padding::model::symmetric);
    std::cout << "printSymmetric: \n";
    for (int y = -pad_size_y; y < mat.sizeY() + pad_size_y; ++y) {
        for (int x = -pad_size_x; x < mat.sizeX() + pad_size_x; ++x) {
            std::cout << mat.at(x, y) << ", ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    mat.removePadding();
}

template<typename DataType>
void printReplicate(hs::raster::RasterView<DataType>& mat)
{
    int pad_size_x = 1;
    int pad_size_y = 1;
    mat.setPadding(pad_size_x, pad_size_y, hs::raster::padding::model::replicate);
    std::cout << "printReplicate: \n";
    for (int y = -pad_size_y; y < mat.sizeY() + pad_size_y; ++y) {
        for (int x = -pad_size_x; x < mat.sizeX() + pad_size_x; ++x) {
            std::cout << mat.at(x, y) << ", ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    mat.removePadding();
}

template<typename DataType>
void printCircular(hs::raster::RasterView<DataType>& mat)
{
    int pad_size_x = 1;
    int pad_size_y = 1;
    mat.setPadding(pad_size_x, pad_size_y, hs::raster::padding::model::circular);
    std::cout << "printCircular: \n";
    for (int y = -pad_size_y; y < mat.sizeY() + pad_size_y; ++y) {
        for (int x = -pad_size_x; x < mat.sizeX() + pad_size_x; ++x) {
            std::cout << mat.at(x, y) << ", ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    mat.removePadding();   
}

template<typename DataType>
void printFill(hs::raster::RasterView<DataType>& mat)
{
    int pad_size_x = 1;
    int pad_size_y = 1;
    mat.setPadding(pad_size_x, pad_size_y, hs::raster::padding::model::fill, hs::raster::padding::direction::both, 1);
    std::cout << "printFill: \n";
    for (int y = -pad_size_y; y < mat.sizeY() + pad_size_y; ++y) {
        for (int x = -pad_size_x; x < mat.sizeX() + pad_size_x; ++x) {
            std::cout << mat.at(x, y) << ", ";
        }
        std::cout << std::endl;
    }
    std::cout << std::endl;
    mat.removePadding();   
}


int main(int argc, char* argv[])
{
    int size_x = 5;
    int size_y = 4;
    float* pdata = new float[size_x * size_y];
    for (int i = 0; i < size_x * size_y; ++i) {
        pdata[i] = i + 1;
    }

    hs::raster::RasterView<float> rdata(size_x, size_y, pdata);
    std::cout << "rdata: \n";
    printmat(rdata);
    std::cout << "Is row major: " << rdata.isRowMajor() << std::endl;
    std::cout << "Nodata: " << rdata.nodata() << std::endl;

    std::cout << std::endl;
    hs::raster::RasterColView<float> cdata;
    cdata.init(size_x, size_y, pdata);
    std::cout << "cdata: \n";
    printmat(cdata);
    std::cout << "Is row major: " << cdata.isRowMajor() << std::endl;
    
    std::cout << std::endl;
    printCircular(rdata);

    std::cout << std::endl;
    printSymmetric(rdata);

    std::cout << std::endl;
    printReplicate(rdata);

    std::cout << std::endl;
    printFill(rdata);

    delete [] pdata;

    return 0;
}

